#include "sys.h"
#include "net.h"
#include "log.h"
#include "devinfo.h"

#define TCAPI_TOOL "/userfs/bin/tcapi"

static void _add_env_path(){
    char *p_path = NULL, new_path[128] = {0};

    p_path = getenv("PATH");
    if(p_path != NULL){
        log_trace("get env PATH:%s", p_path);
        if(strstr(p_path, "/userfs/bin") == NULL){
            sprintf(new_path, "%s:/userfs/bin", p_path);
            setenv("PATH", new_path, 1);
            p_path = getenv("PATH");
            log_trace("new PATH: %s.", p_path);
        }
    }else{
        log_error("Can not find evn PATH, add it...");
        strcpy(new_path, "/userfs/bin:/usr/sbin:/bin:/usr/bin:/sbin");
        setenv("PATH", new_path, 1);
        p_path = getenv("PATH");
        log_trace("new PATH: %s.", p_path);
    }

}

static int _is_first_called(){
    char *p_first_call = NULL;
    char buf[32] = {0};

    p_first_call = getenv("PT622G_FIRST");
    if(p_first_call == NULL){
        strcpy(buf, "1");
        setenv("PT622G_FIRST", buf, 1);
        return 1;
    }else{
        return 0;
    }
    return 0;
}

//友华 pt622g, pt632g
int is_pt622g()
{

    if (access(TCAPI_TOOL, F_OK) != 0) {
        return 0;
    }


    if(_is_first_called()){

        _add_env_path();

        log_trace("/userfs/bin/tcapi set WanInfo_Common CurIFIndex 0");
        system("/userfs/bin/tcapi set WanInfo_Common CurIFIndex 0");
    }
    return 1;
}

int pt622g_is_bridge(){
    int is_bridge = 0;
    int flg_serviceList_internet = 0, flg_wanmode_bridge = 0;
    char buf[128] = { 0 };
    char *delim = "=", *ptr = NULL, *saveptr;
    FILE* fp;

    fp = popen("/userfs/bin/tcapi show Wan", "r");
    log_trace("popen /userfs/bin/tcapi show Wan, fp:%p", fp);
    if(!fp){
        log_syserr("popen /userfs/bin/tcapi show Wan failed.");
    }
    // log_trace("/userfs/bin/tcapi show Wan:");
    while (fgets(buf, sizeof(buf), fp) != NULL) {
        // log_trace("%s", buf);
        if (strstr(buf, "Node:Entry")) {
            flg_serviceList_internet = 0;
            flg_wanmode_bridge = 0;
            continue;
        }

        if (strstr(buf, "ServiceList")) {
            ptr = strtok_r(buf, delim, &saveptr);
            ptr = strtok_r(NULL, delim, &saveptr);
            if (strstr(ptr, "INTERNET")) {
                flg_serviceList_internet = 1;
            }
        }

        if (strstr(buf, "WanMode")) {
            ptr = strtok_r(buf, delim, &saveptr);
            ptr = strtok_r(NULL, delim, &saveptr);
            if (strstr(ptr, "Bridge")) {
                flg_wanmode_bridge = 1;
            }
        }

        if (flg_serviceList_internet && flg_wanmode_bridge) {
            is_bridge = 1;
            break;
        }
    }
    log_trace("pt622g is_bridge :%d", is_bridge);
    pclose(fp);
    return is_bridge;
}

int pt622g_get_internet_r_pwd(char *usr, char *pwd){
    int flg_serviceList_internet = 0, flg_wanmode_route = 0;
    char buf[128] = { 0 };
    char *delim = "=", *ptr = NULL, *saveptr;
    int ret = 0;
    FILE* fp;

    fp = popen("/userfs/bin/tcapi show Wan", "r");
    while (fgets(buf, sizeof(buf), fp) != NULL) {
        if (strstr(buf, "Node:Entry")) {
            flg_serviceList_internet = 0;
            flg_wanmode_route = 0;
            continue;
        }

        if (strstr(buf, "ServiceList")) {
            ptr = strtok_r(buf, delim, &saveptr);
            ptr = strtok_r(NULL, delim, &saveptr);
            if (strstr(ptr, "INTERNET")) {
                flg_serviceList_internet = 1;
            }
        }

        if (strstr(buf, "WanMode")) {
            ptr = strtok_r(buf, delim, &saveptr);
            ptr = strtok_r(NULL, delim, &saveptr);
            if (strstr(ptr, "Route")) {
                flg_wanmode_route = 1;
            }
        }

        if (flg_serviceList_internet && flg_wanmode_route) {
            buf[strlen(buf) - 1] = '\0';
            if(strstr(buf, "USERNAME")){
                ptr = strtok_r(buf, delim, &saveptr);
                ptr = strtok_r(NULL, delim, &saveptr);
                strcpy(usr, ptr);
            }
            if(strstr(buf, "PASSWORD")){
                ptr = strtok_r(buf, delim, &saveptr);
                ptr = strtok_r(NULL, delim, &saveptr);
                strcpy(pwd, ptr);
            }
            if(strlen(usr) > 0 && strlen(pwd) > 0){
                ret = 1;
                break;
            }
        }
    }
    pclose(fp);
    return ret;
}

int pt622g_has_internet()
{
    int has_internet = 0;
    int flg_serviceList_internet = 0, flg_wanmode_route = 0;
    char buf[128] = { 0 };
    char *delim = "=", *ptr = NULL, *saveptr;
    FILE* fp;

    fp = popen("/userfs/bin/tcapi show Wan", "r");
    while (fgets(buf, sizeof(buf), fp) != NULL) {
        if (strstr(buf, "Node:Entry")) {
            flg_serviceList_internet = 0;
            flg_wanmode_route = 0;
            continue;
        }

        if (strstr(buf, "ServiceList")) {
            ptr = strtok_r(buf, delim, &saveptr);
            ptr = strtok_r(NULL, delim, &saveptr);
            if (strstr(ptr, "INTERNET")) {
                flg_serviceList_internet = 1;
            }
        }

        if (strstr(buf, "WanMode")) {
            ptr = strtok_r(buf, delim, &saveptr);
            ptr = strtok_r(NULL, delim, &saveptr);
            if (strstr(ptr, "Route")) {
                flg_wanmode_route = 1;
            }
        }

        if (flg_serviceList_internet && flg_wanmode_route) {
            has_internet = 1;
            break;
        }
    }
    log_trace("pt622g has internet :%d", has_internet);
    pclose(fp);
    return has_internet ; //return 0:not bridge, 1:bridge
}
static void _tcapi_show_deviceinfo(char* buffer, char* name)
{
    char* cmd = "/userfs/bin/tcapi show DeviceInfo";
    char buf[128] = { 0 };
    char *delim = "=", *ptr, *saveptr;
    FILE* fp;

    fp = popen(cmd, "r");
    while (fgets(buf, sizeof(buf), fp)) {
        buf[strlen(buf) - 1] = 0;
        if (strstr(buf, name)) {
            ptr = strtok_r(buf, delim, &saveptr);
            ptr = strtok_r(NULL, delim, &saveptr);
            strcpy(buffer, ptr);
            // log_trace("buf:%s, ptr:%s", buf, ptr);
            break;
        }
    }
    pclose(fp);
}
void pt622g_get_mac(char* mac)
{
    getifaddr("pon", mac, "mac");
}
static void _get_loid_info(char *loid, char *loidKey){
    FILE *fp;
    char buf[128] = {0};
    char *delim = "=", *ptr, *saveptr;

    fp = popen("/userfs/bin/tcapi show LOIDAuth", "r");
    while(fgets(buf, sizeof(buf), fp) != NULL){
        
        buf[strlen(buf) - 1] = '\0';

        if(strstr(buf, "LOID")){
            ptr = strtok_r(buf, delim, &saveptr);
            ptr = strtok_r(NULL, delim, &saveptr);
            if(ptr)
                strcpy(loid, ptr);
        }
        if(strstr(buf, "Password")){
            ptr = strtok_r(buf, delim, &saveptr);
            ptr = strtok_r(NULL, delim, &saveptr);
            if(ptr)
                strcpy(loidKey, ptr);
        }
    }
}
void pt622g_get_devinfo(DevInfo_t* devinfo)
{
    char buffer[128] = { 0 }, SN[32] = { 0 }, OUI[32] = { 0 };
    strcpy(devinfo->factory, "YouHua");

    _tcapi_show_deviceinfo(buffer, "ProductClass");
    if(strlen(buffer) == 0){
        _tcapi_show_deviceinfo(buffer, "ModelName");
    }
    strcpy(devinfo->model, buffer);


    _tcapi_show_deviceinfo(buffer, "CustomerSWVersion");
    strcpy(devinfo->sw_version, buffer);

    _tcapi_show_deviceinfo(OUI, "ManufacturerOUI");
    _tcapi_show_deviceinfo(SN, "SerialNum");
    bzero(buffer, sizeof(buffer));
    strcat(buffer, OUI);
    strcat(buffer, "-");
    strcat(buffer, SN);
    strcpy(devinfo->gatewaySN, buffer);

    _get_loid_info(devinfo->loid, devinfo->loidKey);

    get_os_version(devinfo->osVersion);

    strcpy(devinfo->osType, "Linux");
    strcpy(devinfo->dev_type, "ONT");
    devinfo->clientPattern = pt622g_is_bridge() ? 2 : 1; // 1:router 2:bridge
    devinfo->flashSize = 0;

    // system("/userfs/bin/tcapi show DeviceInfo > devinfo.log");
}